# -*- coding: utf-8 -*-
# standard
import os
import sys

# third
from celery.schedules import crontab
from celery import Celery

# local
_P_PATH =  os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
if _P_PATH not in sys.path:
    sys.path.append(_P_PATH)
from models.celery_conf import CELERY_APP
from functions.event_func import *


"""
@Title:  celery 的周期性任务 
@File: periodic_func.py
@Author: walle 2025年01日09日 11时37分07秒
@Version: 1.0.0
@Desc: 
https://docs.celeryq.dev/en/stable/userguide/periodic-tasks.html
add_periodic_task 函数用于增加周期性任务：
第一个参数是周期性信息 典型的是 crontab 的实例
第二个参数是周期性函数
expires: 过期时间，单位秒

test.s 其实是 test.signature 的简写.
s的第一个参数: 相当于 魔法参数中的 args 如果只有一个参数，你可以直接传递，celery会自己把这个参数转为 tuple 对象
s的第二个参数： 相当于 魔法参数中的 kwargs
test.s(2, 2).set(countdown=10).set(expires=30).delay()
et(countdown=10) 表示延迟 10秒
set(expires=30) 表示过期超过30秒就不再执行了
delay() 意思就是延迟调用

crontab 用于定义周期性的信息，的常见用法
crontab(minute=0, hour=0)        每天零点执行
crontab(minute=0, hour='*/3')    每间隔3个小时执行一次
crontab(minute=0, hour='9,18')   在每天的9点和18点各执行一次(条件中的逗号表示 and 的意思)
crontab(minute='*/15')           每15分钟执行一次
day_of_month='2-30/2')           偶数日执行
crontab(0, 0, day_of_month='2')  每个月的第二天的零点执行一次
crontab(minute='*/10',hour='*', day_of_week='thu,sun')   星期四和星期六每个小时的第10分钟执行一次
crontab(minute=0, hour='*/2,*/3')  每个既能被2整除又能被3整除的小时候的0分钟执行
crontab(0, 0, day_of_month='11', month_of_year='5')  每年5月11日零点执行
...
crontab 常用参数：
minute:  分钟
hour: 小时
day_of_week: 星期
day_of_month: 天
month_of_year: 月
"""


# @CELERY_APP.on_after_configure.connect
# def setup_periodic_tasks(sender: Celery, **kwargs):
#     """
#     设置周期性的任务
#     """
#     sender.add_periodic_task(
#         crontab(hour="*", minute="0"),
#         test.s('Happy Mondays!', ),
#     )

# @CELERY_APP.task
# def test(arg):
#     print(arg)

# @CELERY_APP.task
# def add(x, y):
#     z = x + y
#     print(z)

# todo： 暂时使用同步任务模式 2025-7-18


@CELERY_APP.task
def checkout_task_from_db():
    """
    从数据库检出任务放入工作队列
    """
    end_time = datetime.now() + timedelta(seconds=BEAT_INTERVAL * 60)
    db_session = new_db_session(sync=True)
    s = select(
        OutPushTaskOrm
    ).where(
        OutPushTaskOrm.status == PushTaskStatus.PENDING.value,
        OutPushTaskOrm.plan_time <= end_time
    )
    tasks = db_session.scalars(s).all()
    db_session.close()
    logger.debug(f"检索到{len(tasks)}个近期任务")
    for task in tasks:
        kw = task.to_dict()
        kw['mic_service_source'] = MicServiceSource(kw['title'])
        push_task = OutPushTask(**kw)
        push_task.add_to_task_queue()



@CELERY_APP.on_after_configure.connect
def setup_periodic_tasks(sender: Celery, **kwargs):
    """
    设置周期性的任务
    """
    logger.debug(f"setup_periodic_tasks begin execute....")
    if isinstance(BEAT_INTERVAL, int) and BEAT_INTERVAL > 0:
        minute = "*" if BEAT_INTERVAL == 1 else f"*/{BEAT_INTERVAL}"
    else:
        raise ValueError("BEAT_INTERVAL 必须是一个正整数")
    # 添加定期推送消息的任务
    sender.add_periodic_task(
        crontab(hour="*", minute=minute),
        checkout_task_from_db.s(),
    )
    logger.debug("setup_periodic_tasks execute end.")


if __name__ == '__main__':
    checkout_task_from_db()
    pass